#ifndef FILESYSTEM_H
#define FILESYSTEM_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

// 定义常量
#define MAX_FILENAME 20       // 文件名最大长度
#define MAX_BLOCKS 1024        // 磁盘块总数
#define BLOCK_SIZE 1024        // 每个磁盘块的大小（字节）
#define MAX_FILE_SIZE 10240    // 文件最大大小
#define MAX_OPEN_FILES 10      // 最大同时打开文件数
#define MAX_DIR_ENTRIES 32     // 目录最大条目数

// 文件类型枚举
typedef enum {
    FILE_TYPE,    // 普通文件
    DIR_TYPE      // 目录文件
} FileType;

// 磁盘块结构
typedef struct {
    char data[BLOCK_SIZE];
} DiskBlock;

// 索引节点结构
typedef struct {
    int inode_id;        // 索引节点ID
    FileType type;       // 文件类型
    int size;            // 文件大小
    int blocks[10];      // 直接块索引（最多10个块）
    time_t create_time;  // 创建时间
    time_t modify_time;  // 修改时间
} Inode;

// 文件目录项结构
typedef struct {
    char name[MAX_FILENAME];  // 文件名
    int inode_id;             // 对应的索引节点ID
    FileType type;            // 文件类型
} DirEntry;

// 打开文件表项结构
typedef struct {
    int inode_id;        // 对应的索引节点ID
    int offset;          // 当前读写位置
    int flags;           // 打开标志（0:读, 1:写, 2:读写）
    int valid;           // 是否有效
} OpenFile;

// 模拟文件系统结构
typedef struct {
    DiskBlock blocks[MAX_BLOCKS];   // 模拟磁盘块
    Inode inodes[MAX_BLOCKS];       // 索引节点表
    OpenFile open_files[MAX_OPEN_FILES]; // 打开文件表
    DirEntry root_dir[MAX_DIR_ENTRIES]; // 根目录
    int free_block_map[MAX_BLOCKS]; // 空闲块位图
    int free_inode_map[MAX_BLOCKS]; // 空闲inode位图
    int current_inode;              // 当前目录的inode
} FileSystem;

// 函数声明
void init_filesystem(FileSystem *fs);
int create_file(FileSystem *fs, const char *name);
int create_dir(FileSystem *fs, const char *name);
int open_file(FileSystem *fs, const char *name, int flags);
int close_file(FileSystem *fs, int fd);
int write_file(FileSystem *fs, int fd, const char *buffer, int size);
int read_file(FileSystem *fs, int fd, char *buffer, int size);
int delete_file(FileSystem *fs, const char *name);
int list_dir(FileSystem *fs, const char *dir_name);
int change_dir(FileSystem *fs, const char *dir_name);
int get_inode_by_name(FileSystem *fs, const char *name, DirEntry *entries, int entry_count);
int allocate_block(FileSystem *fs);
int allocate_inode(FileSystem *fs);
void free_block(FileSystem *fs, int block_id);
void free_inode(FileSystem *fs, int inode_id);
void format_filesystem(FileSystem *fs);

#endif // FILESYSTEM_H